package cn.blnp.net.flowable.multiple.service;

import cn.hutool.core.map.MapUtil;
import lombok.extern.slf4j.Slf4j;
import org.assertj.core.util.Lists;
import org.flowable.engine.*;
import org.flowable.engine.repository.Deployment;
import org.flowable.engine.repository.ProcessDefinition;
import org.flowable.engine.runtime.ProcessInstance;
import org.flowable.task.api.Task;
import org.junit.jupiter.api.Test;
import org.springframework.boot.test.context.SpringBootTest;

import javax.annotation.Resource;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

/**
 * <h3>多实例-服务任务应用实战</h3>
 *
 * @author <a href="mailto:blnp.yibin@qq.com">lyb</a>
 * @version 1.0
 * @since 2025/5/22 16:14
 */
@Slf4j
@SpringBootTest
public class MultipleInsServiceTaskTest {

    @Resource
    private RepositoryService repositoryService;
    @Resource
    private RuntimeService runtimeService;
    @Resource
    private TaskService taskService;
    @Resource
    private HistoryService historyService;
    @Resource
    private ManagementService managementService;


    /**
     *  <h2>多实例服务应用</h2>
     *  <p>
     *      与用户任务需要人工参与不同，服务任务可以自动完成，不需要任何人工干涉。服务任务可以同时执行一些自己的逻辑代码，同样支持设置为多实例，可用于需要自动运行的多实例，
     *   如向多个用户发送信息、邮件等。下面看一个多实例服务任务的使用示例，其流程如图所示。流程发起后进入用户任务节点，提交人员名单，然后进入并行多实例服务任务发送录用通知。
     *      <b>流程定义文件：</b>{@link flow/multiServiceTaskProcess.bpmn20.xml}<br/>
     *      <b>流程预览图：</b><br/>
     *      <img src="https://cdn4.winhlb.com/2025/05/22/682edf280264b.png" />
     *  </p>
     *
     **/
    @Test
    public void test() {
        Deployment deploy = repositoryService.createDeployment()
                .name("服务任务多实例实战-演示案例")
                .addClasspathResource("flow/multiServiceTaskProcess.bpmn20.xml")
                .deploy();
        log.info("部署流程定义：{}", deploy.getId());
        ProcessDefinition procDef = repositoryService.createProcessDefinitionQuery()
                .deploymentId(deploy.getId())
                .singleResult();
        log.info("流程定义编号：{}", procDef.getId());
        //设置流程变量
        Map<String, Object> varMap1 = MapUtil.builder(new HashMap<String, Object>())
                .put("lender", "张三")
                .build();
        //启动流程实例
        ProcessInstance procInst = runtimeService.startProcessInstanceById(procDef.getId(), varMap1);

        //查询第一个任务
        Task userTask1 = taskService.createTaskQuery()
                .processInstanceId(procInst.getId()).singleResult();
        log.info("即将完成第一个任务，当前任务名称：{}", userTask1.getName());
        //设置流程变量
        List<String> userIds = Lists.newArrayList("张三", "李四", "赵六");
        Map<String, Object> varMap = MapUtil.builder(new HashMap<String, Object>())
                .put("userIdList", userIds)
                .build();
        //完成第一个任务
        taskService.complete(userTask1.getId(), varMap);

        /**
         *  演示结果：
         *  2025-05-22 16:28:35.756  INFO 73280 --- [           main] c.b.n.f.m.s.MultipleInsServiceTaskTest   : 部署流程定义：c0c1329e-36e6-11f0-bc88-50ebf6ec8f6d
         * 2025-05-22 16:28:35.760  INFO 73280 --- [           main] c.b.n.f.m.s.MultipleInsServiceTaskTest   : 流程定义编号：multiServiceTaskProcess:2:c1062ae1-36e6-11f0-bc88-50ebf6ec8f6d
         * 2025-05-22 16:28:35.779  INFO 73280 --- [           main] c.b.n.f.config.FlowableLoggingListener   : 流程启动 | 实例ID:c10da4f4-36e6-11f0-bc88-50ebf6ec8f6d | 定义ID:multiServiceTaskProcess:2:c1062ae1-36e6-11f0-bc88-50ebf6ec8f6d
         * 2025-05-22 16:28:35.780 DEBUG 73280 --- [           main] c.b.n.f.config.FlowableLoggingListener   : 节点进入 | 类型:startEvent | ID:startEvent1
         * 2025-05-22 16:28:35.784 DEBUG 73280 --- [           main] c.b.n.f.config.FlowableLoggingListener   : 节点进入 | 类型:userTask | ID:userTask1
         * 2025-05-22 16:28:35.794  INFO 73280 --- [           main] c.b.n.f.config.FlowableLoggingListener   : 任务创建 | ID:c1103d08-36e6-11f0-bc88-50ebf6ec8f6d | 名称:提交人员名单 | 处理人:null
         * 2025-05-22 16:28:35.865  INFO 73280 --- [           main] c.b.n.f.m.s.MultipleInsServiceTaskTest   : 即将完成第一个任务，当前任务名称：提交人员名单
         * 2025-05-22 16:28:35.890 DEBUG 73280 --- [           main] c.b.n.f.config.FlowableLoggingListener   : 节点进入 | 类型:serviceTask | ID:serviceTask1
         * 2025-05-22 16:28:35.891  INFO 73280 --- [           main] c.b.n.f.m.s.SendOfferLetterDelegate      : 第1位录取人员张三的录用通知发送成功！
         * 2025-05-22 16:28:35.891  INFO 73280 --- [           main] c.b.n.f.m.s.SendOfferLetterDelegate      : 通过属性注入的userIdField属性值为：张三
         * 2025-05-22 16:28:35.901 DEBUG 73280 --- [           main] c.b.n.f.config.FlowableLoggingListener   : 节点进入 | 类型:serviceTask | ID:serviceTask1
         * 2025-05-22 16:28:35.902  INFO 73280 --- [           main] c.b.n.f.m.s.SendOfferLetterDelegate      : 第2位录取人员李四的录用通知发送成功！
         * 2025-05-22 16:28:35.902  INFO 73280 --- [           main] c.b.n.f.m.s.SendOfferLetterDelegate      : 通过属性注入的userIdField属性值为：李四
         * 2025-05-22 16:28:35.902 DEBUG 73280 --- [           main] c.b.n.f.config.FlowableLoggingListener   : 节点进入 | 类型:serviceTask | ID:serviceTask1
         * 2025-05-22 16:28:35.902  INFO 73280 --- [           main] c.b.n.f.m.s.SendOfferLetterDelegate      : 第3位录取人员赵六的录用通知发送成功！
         * 2025-05-22 16:28:35.902  INFO 73280 --- [           main] c.b.n.f.m.s.SendOfferLetterDelegate      : 通过属性注入的userIdField属性值为：赵六
         * 2025-05-22 16:28:35.911 DEBUG 73280 --- [           main] c.b.n.f.config.FlowableLoggingListener   : 节点进入 | 类型:endEvent | ID:endEvent1
         **/
    }
}
